﻿using System;
using System.Collections;
using System.Collections.Generic;
using System.ComponentModel;
using System.Linq;
using System.Reflection;
using System.Text;
using System.Web.UI;
using System.Web.UI.WebControls;

namespace Web.Framework.Controls
{
    //cPlanProdMain
    //cPlanProdTable
    //cPlanProdRowPar
    //cPlanProdRowImpar
    //cPlanProdTableHeader
    //cPlanProdInvisible
    //cPlanProdInputCant
    //cPlanProdTdTotal
    //cPlanProdInputTotal

    [DefaultProperty("Text"), ToolboxData("<{0}:GridCtrl runat=server></{0}:GridCtrl>")]
    public class GridCtrl : WebControl
    {
        public IList DataSource { get; set; }

        public List<ColumnMetadata> ColumnMetadataCollection { get; set; }

        public int CellPadding { get; set; }

        public int CellSpacing { get; set; }

        public int TableBorder { get; set; }

        public string ExpandImageSrc { get; set; }

        public string CollapseImageSrc { get; set; }     

        protected override void Render(HtmlTextWriter output)
        {
            CellPadding = 2;

            StringBuilder builder = new StringBuilder();
            builder.AppendFormat("<div class='cPlanProdMain' id='{0}' expandimagesrc='{1}' collapseimagesrc='{2}' >", this.ClientID, this.ExpandImageSrc, this.CollapseImageSrc);

            DrawTable(builder, this.DataSource, this.ColumnMetadataCollection, 0);

            builder.Append("</div>");

            output.Write(builder.ToString());
        }

        private void DrawTable(StringBuilder builder, IList dataSource, List<ColumnMetadata> columnMetadataCollection, int nivelDeProfundidad = 0)
        {
            if (dataSource != null || nivelDeProfundidad == 0)
            {

                if (columnMetadataCollection == null || columnMetadataCollection.Count == 0)
                {
                    builder.Append("Should specify grid columns");
                }
                else
                {

                    builder.AppendFormat("<table cellpadding='{0}' cellspacing='{1}' border='{2}' class='cPlanProdTable nivelProdundidad_{3}' id='table_{5}_{6}' {4}  >", CellPadding, CellSpacing, TableBorder, nivelDeProfundidad, nivelDeProfundidad == 0 ? "width='100%'" : string.Empty, this.ClientID, nivelDeProfundidad);

                    // Header
                    builder.Append("<tr class='cPlanProdTableHeader' >");

                    // Si existe una subgrilla muestro el botón de expandir
                    bool showExpandir = columnMetadataCollection.Where(c => c.IsNestedList).Count() > 0;
                    if (showExpandir)
                    {
                        builder.Append("<td class='cPlanProdEliminarHeader' ></td>");
                    }

                    columnMetadataCollection = columnMetadataCollection.OrderBy(c => c.Order).ToList();

                    foreach (ColumnMetadata cm in columnMetadataCollection)
                    {
                        builder.AppendFormat("<td class='cPlanProdSemTd {1}'>{0}</td>", cm.ColumnDescription, cm.Visible ? "" : "displayNone");
                    }

                    builder.Append("</tr>");
                    // fin header

                    // Dibujo el body de la tabla
                    DrawGridRows(builder, dataSource, columnMetadataCollection, showExpandir, nivelDeProfundidad);

                    builder.Append("</table>");
                }
            }
        }

        private void DrawGridRows(StringBuilder builder, IList dataSource, List<ColumnMetadata> columnMetadataCollection, bool showExpandir, int nivelDeProfundidad = 0)
        {
            if (dataSource != null && dataSource.Count > 0)
            {
                int fila = 0;
                int columna = 0;

                Type tipoDataSource = dataSource[0].GetType();

                PropertyInfo[] propertiesInfo = tipoDataSource.GetProperties();

                bool esPar = false;
                foreach (object dataItem in dataSource)
                {
                    esPar = !esPar;
                    object dataItemValue = null;
                    builder.AppendFormat("<tr class='{0}' id='tr_row_{1}' >", esPar ? "cPlanProdRowPar" : "cPlanProdRowImpar", fila);

                    // Guardo las variables necesarias para las subgrilla interior
                    IList innerDataSource = null;
                    bool hasNested = false;
                    List<ColumnMetadata> columnNestedMetadataCollection = null;
                    
                    if (showExpandir)
                    {
                        ColumnMetadata cmNested = columnMetadataCollection.Where(cm => cm.IsNestedList).Single();
                        PropertyInfo propertyInfo = propertiesInfo.Where(p => p.Name == cmNested.ColumnNameProperty).Single();
                        dataItemValue = propertyInfo.GetValue(dataItem, null);
                        if (dataItemValue != null && (dataItemValue as IList).Count > 0)
                        {
                            builder.AppendFormat("<td><img src='{0}' class='imgExpandCollapse_{2}_{1} imgExpandCollpse' innerId='imgExpandCollapse_{2}_{1}' nivel='{2}' /></td>", CollapseImageSrc, fila, nivelDeProfundidad);
                        }
                        else
                        {
                            builder.Append("<td></td>");
                        }
                    }

                    foreach (ColumnMetadata cm in columnMetadataCollection)
                    {                        
                        columna = 0;
                        PropertyInfo propertyInfo = propertiesInfo.Where(p => p.Name == cm.ColumnNameProperty).Single();

                        dataItemValue = propertyInfo.GetValue(dataItem, null);

                        if (cm.IsNestedList)
                        {
                            hasNested = true;
                            innerDataSource = dataItemValue as IList;
                            columnNestedMetadataCollection = cm.ColumnNestedMetadataCollection;
                        }
                        else
                        {
                            if (!String.IsNullOrEmpty(cm.FormatString))
                            {
                                dataItemValue = string.Format("{0:" + cm.FormatString + "}", dataItemValue);
                            }

                            string isVisible = cm.Visible ? string.Empty : "displayNone";
                            builder.AppendFormat("<td class='cPlanProdDataTd {1}' databound='{2}' column='{3}'>{0}</td>", dataItemValue, isVisible, cm.ColumnNameProperty, columna);

                            columna++;
                        }
                    }

                    builder.Append("</tr>");

                    // Si necesita una grilla nested la agrego
                    if (hasNested && innerDataSource != null && innerDataSource.Count > 0)
                    {
                        // Dibujo la linea de mas                                              
                        builder.AppendFormat("<tr class='trExpansible_{2}_{1}' style='display:none;' ><td colspan='{0}' nivel='{2}' >", columnMetadataCollection.Count, fila, nivelDeProfundidad);

                        DrawTable(builder, innerDataSource, columnNestedMetadataCollection, nivelDeProfundidad + 1);

                        builder.Append("</td></tr>");
                    }

                    fila++;
                }
            }
        }
    }
}
